<template>
  <div>
    <a-card>
      <div slot="title">{{ title }}</div>
      <div slot="extra">
        <a-button size="small" type="" @click="addFirstLevel"><i class="fa fa-plus-circle mr5"></i>节点</a-button>
      </div>
      <div class="scroll" style="min-height:400px;">
        <div class="tac" style="padding:30px 0;" v-show="!showTree">
          <a-spin tip="数据加载中..."/>
        </div>
        <a-tree
          v-if="showTree"
          class="draggable-tree"
          draggable
          :treeData="treeData"
          :defaultExpandAll="defaultExpandAll"
          :autoExpandParent="autoExpandParent"
          :load-data="onLoadData"
          @drop="onDrop"
        >
          <div class="tree-btns" slot="titleWithBtn" slot-scope="item">
            <span class="title" @click="click(item)">{{ item.title }}</span>
            <span class="add" @click.stop="add(item)"><a-icon title="添加子节点" type="plus-circle" /></span>
            <span class="del" @click.stop="del(item)"><a-icon title="删除节点" type="close-circle" /></span>
          </div>
        </a-tree>
      </div>
    </a-card>
  </div>
</template>

<script>
export default {
  props: {
    title: {
      type: String,
      default: '树管理'
    },
    url: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      showTree: false,
      defaultExpandAll: false,
      autoExpandParent: true,
      treeData: []
    }
  },
  mounted () {
    this.search()
  },
  methods: {
    search () {
      this.$http.get('${baseMapping}/first', {}, data => {
        this.treeData = data
        this.showTree = true
      })
    },
    onLoadData (treeNode) {
      const that = this
      return new Promise(resolve => {
        if (treeNode.dataRef.children.length > 0) {
          resolve()
          return
        }
        that.$http.get('${baseMapping}/child', { pid: treeNode.dataRef.key }, data => {
          treeNode.dataRef.children = data
          that.treeData = [...that.treeData]
          resolve()
        })
      })
    },
    click (item) {
      this.$emit('click', { key: item.key, title: item.title })
    },
    delNode (node, arr) {
      for (let s = 0; s < arr.length; s++) {
        if (arr[s].key === node.key) {
          arr.splice(s, 1)
        } else if (arr[s].children && arr[s].children.length > 0) {
          this.delNode(node, arr[s].children)
        } else {
          continue
        }
      }
    },
    updateNode (node, arr) {
      for (let s = 0; s < arr.length; s++) {
        if (arr[s].key === node.key) {
          arr[s].title = node.title
        } else if (arr[s].children && arr[s].children.length > 0) {
          this.updateNode(node, arr[s].children)
        } else {
          continue
        }
      }
    },
    addFirstLevel () {
      this.$http.post('${baseMapping}/add', { pid: 0 }, data => {
        data.children = []
        this.treeData.push(data)
      })
    },
    add (item) {
      this.$http.post('${baseMapping}/add', { pid: item.dataRef.key }, data => {
        data.children = []
        item.children.push(data)
      })
    },
    del (item) {
      const that = this
      that.confirm(() => {
        that.$http.post('${baseMapping}/del', { id: item.dataRef.key }, data => {
          that.delNode(item, that.treeData)
        })
      })
    },
    onDrop (info) {
      const that = this
      const dropKey = info.node.eventKey
      const dragKey = info.dragNode.eventKey
      const dropPos = info.node.pos.split('-')
      const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1])

      const loop = (data, key, callback) => {
        data.forEach((item, index, arr) => {
          if (item.key === key) {
            return callback(item, index, arr)
          }
          if (item.children) {
            return loop(item.children, key, callback)
          }
        })
      }
      const newTreeData = [...this.treeData]

      // Find dragObject
      let dragObj
      loop(newTreeData, dragKey, (item, index, arr) => {
        arr.splice(index, 1)
        dragObj = item
      })
      if (!info.dropToGap) {
        // Drop on the content
        loop(newTreeData, dropKey, item => {
          item.children = item.children || []
          // where to insert 示例添加到尾部，可以是随意位置
          item.children.push(dragObj)
        })
      } else if (
        (info.node.children || []).length > 0 && // Has children
        info.node.expanded && // Is expanded
        dropPosition === 1 // On the bottom gap
      ) {
        loop(newTreeData, dropKey, item => {
          item.children = item.children || []
          // where to insert 示例添加到尾部，可以是随意位置
          item.children.unshift(dragObj)
        })
      } else {
        let ar
        let i
        loop(newTreeData, dropKey, (item, index, arr) => {
          ar = arr
          i = index
        })
        if (dropPosition === -1) {
          ar.splice(i, 0, dragObj)
        } else {
          ar.splice(i + 1, 0, dragObj)
        }
      }
      // alert('把' + dragKey + '拖拽到' + dropKey + '的' + (dropPosition === -1 ? '前面' : dropPosition === 0 ? '里面' : dropPosition === 1 ? '后面' : ''))
      that.$http.post('${baseMapping}/drop', { dragId: dragKey, dropId: dropKey, position: dropPosition }, data => {
        that.treeData = newTreeData
      })
    },
    rename (item, newName) {
      const that = this
      item.title = newName
      that.updateNode(item, that.treeData)
    }
  }
}
</script>
<style lang="less" scoped>
.tree-btns{
  &:hover{
    .add,.del,.rename{
      display:inline-block;
    }
  }
  .add,.del,.rename{
    display:none;
    margin-left:10px;
    &:hover{
      font-weight:800;
    }
  }
  .add{
    color:green;
  }
  .del{
    color:red;
  }
  .rename{
    color:blue;
  }
}
</style>
